package edu.zut.cs.network.service.impl;

import java.io.IOException;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import edu.zut.cs.network.dao.BookDao;
import edu.zut.cs.network.dao.impl.BookDaoImpl;
import edu.zut.cs.network.entity.Book;
import edu.zut.cs.network.runnable.GetAllRunnable;
import edu.zut.cs.network.runnable.InnerReader;
import edu.zut.cs.network.runnable.InnerWriter;
import edu.zut.cs.network.runnable.InsertRunnable;
import edu.zut.cs.network.service.BookManager;
import edu.zut.cs.network.socket.Client;
import edu.zut.cs.network.socket.Server;

public class BookManagerImpl extends BookDaoImpl implements BookManager {
	static ThreadPoolExecutor pools = getThreadPool();// 定义线程池

	private static ThreadPoolExecutor getThreadPool() {// 获得线程池
		/*
		 * public ThreadPoolExecutor(int corePoolSize, 核心线程数最大值 int maximumPoolSize,
		 * 线程总数最大值 long keepAliveTime, 非核心线程闲置超时时长 TimeUnit unit, keepAliveTime的单位
		 * BlockingQueue<Runnable> workQueue, 线程池中的任务队列 RejectedExecutionHandler
		 * handler) 抛出异常专用的
		 */
		return new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10),
				new ThreadPoolExecutor.CallerRunsPolicy());
	}

	public BookManagerImpl() throws SQLException {
		super();
	}

	BookDao book = new BookDaoImpl();

	@Override
	public List<Book> findByName(String name) {
		return book.findByName(name);
	}

	@Override
	public int insert(List<Book> bookList, String tableName) {

		return book.insert(bookList, tableName);
	}

	@Override
	public List<Book> getAll(String tableName) {
		return book.getAll(tableName);
	}

	@Override
	public int delete(String name) {
		return book.delete(name);
	}

	@Override
	public int upDate(List<Book> bookList) {
		return book.upDate(bookList);
	}

	@Override
	public Book findById(Long id) {
		return book.findById(id);
	}

	@Override
	public void exportToCSV(String filepath, String tableName) {
		book.exportToCSV(filepath, tableName);

	}

	@Override
	public void createTable(String tableName) {
		book.createTable(tableName);

	}

	@Override
	public void importFromCSV(String filepath, String tableName) {
		book.importFromCSV(filepath, tableName);

	}

	@Override
	public void exportToJson(String filepath, String tableName) {
		book.exportToJson(filepath, tableName);

	}

	@Override
	public void importFromJson(String filepath, String tableName) {
		book.importFromJson(filepath, tableName);

	}

	@Override
	public void mulitImportFromCSV(String filePath, String tableName) {
		boolean done = true;
		final int DEFAULT_QUEUE_SIZE = 10;
		BlockingQueue<List<Book>> blockingQueue = new ArrayBlockingQueue<>(DEFAULT_QUEUE_SIZE); // 定义阻塞队列
		pools.execute(new InnerReader(blockingQueue, filePath, DEFAULT_QUEUE_SIZE));
		while (done) {
			if (blockingQueue.isEmpty()) {// 队列为空线程等待一秒钟
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			List<Book> bookList;

			try {
				bookList = blockingQueue.take();// 取队列头元素并移除

				if (bookList != null && bookList.isEmpty()) {
					logger.info("process the big file done.");
					done = false;
				}
				if (done) {
					pools.execute(new InsertRunnable(bookList, tableName));
				}

			} catch (SQLException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
		pools.shutdown();
		try {
			pools.awaitTermination(1, TimeUnit.HOURS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void mulitExportToCSV(String filePath, String tableName) {
		boolean done = true;
		final int DEFAULT_QUEUE_SIZE = 10;
		BlockingQueue<List<Book>> blockingQueue = new ArrayBlockingQueue<>(DEFAULT_QUEUE_SIZE); // 定义阻塞队列
		try {
			pools.execute(new GetAllRunnable(blockingQueue, tableName));
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		while (done) {
			if (blockingQueue.isEmpty()) {// 队列为空线程等待一秒钟
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			List<Book> bookList;
			try {
				bookList = blockingQueue.take();// 取队列头元素并移除
				if (bookList != null && bookList.isEmpty()) {
					logger.info("export the big data done.");
					done = false;
				}
				if (done) {
					pools.execute(new InnerWriter(bookList, filePath));
					TimeUnit.MILLISECONDS.sleep(100);//防止循环太快导致数据出错
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
		pools.shutdown();
		try {
			pools.awaitTermination(1, TimeUnit.HOURS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void serverForClient() {
		try {
			Server server=new Server();
			server.service();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public void clientToServer() {
		try {
			Client client=new Client();
			client.request();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}
